package com.xjoyt.pay.gateway.dao.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.Predicate;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;

import com.xjoyt.pay.abstracts.AbstractDao;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.gateway.dao.InvokeLogRepositoryCustom;
import com.xjoyt.pay.gateway.params.InvokeLogParam;
import com.xjoyt.pay.gateway.po.InvokeLog;
import com.xjoyt.pay.gateway.repository.InvokeLogRepository;

public class InvokeLogRepositoryImpl extends AbstractDao
        implements InvokeLogRepositoryCustom {

    @Autowired
    private InvokeLogRepository repository;

    @Override
    public PageResult<InvokeLog> loadPage(PageParam<InvokeLogParam> param) {
        Pageable pageable = getPageable(param);
        Specification<InvokeLog> spec = getSpecification(param.query);
        Page<InvokeLog> pageReuslt = repository.findAll(spec, pageable);
        return new PageResult<>(pageReuslt.getTotalElements(),
                pageReuslt.getContent());
    }

    private Specification<InvokeLog> getSpecification(InvokeLogParam param) {
        Specification<InvokeLog> spec = (root, query, cb) -> {
            if (param == null) {
                return null;
            }
            List<Predicate> list = new ArrayList<>();
            if (StringUtils.isNotBlank(param.distributorId)) {
                list.add(cb.equal(root.get("distributorId"),
                        param.distributorId));
            }
            if (StringUtils.isNotBlank(param.query)) {
                for (String string : param.query.split(" ")) {
                    if (StringUtils.isBlank(string))
                        continue;
                    String like = "%" + string + "%";
                    list.add(cb.or(cb.like(root.get("companyName"), like),
                            cb.like(root.get("name"), like),
                            cb.like(root.get("merchantName"), like)));
                }
            }
            if (param.success != null) {
                if (param.success)
                    list.add(cb.equal(root.get("success"), param.success));
                else
                    list.add(cb.or(cb.equal(root.get("success"), false),
                            cb.isNull(root.get("success"))));
            }
            if (CollectionUtils.isNotEmpty(list))
                query.where(cb.and(list.toArray(new Predicate[list.size()])));

            return null;
        };
        return spec;
    }

}
